<?php
// +----------------------------------------------------------------------
// | snake
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: NickBai <1902822973@qq.com>
// +----------------------------------------------------------------------
namespace app\common\controller;

use think\facade\Request;
use think\facade\Validate;

class AdminController extends BaseController
{
    public $adminId = 0;
    public $noCheckAction = [];  // 不验证的action

    public $modelName = '';
    public $controllerName = '';
    public $templatePreFix = 'common/base_';

    private $selectList = [];

    public $noProjectAction = [] ; // 不带 project id 的 控制器

    public function __construct($modelName = '',$controllerName = ''){
        if (!empty($modelName)) {
            $this->modelName = $modelName;
        }
        if (!empty($controllerName)) {
            $this->controllerName = $controllerName;
        }
        parent::__construct();
    }

    public function initialize()
    {
        $alj = new \app\common\logic\AdminLogic('Admin');
        $this->adminId = $alj->_is_login();

        if(empty($this->adminId)){
            $this->reLogin('请先登录！');
        }
        // false 验证不通过
//        if(!$this->checkProjectAuthority()){
//            $this->reLogin('登录信息遗失，请重新登陆！');
//        }

        $this->assign('myProjectList', getMyProject());

        parent::initialize();
        $action = Request::action();
        $module = Request::module();
        $controller = Request::controller();
        $url = $module . '/' . $controller . '/' . $action;
        if(!in_array($action,$this->noCheckAction)){
            $check = $alj->_checkAuth($url);
            if(!$check){
                $this->error('你没有权限访问');
            }
        }
        if(!Request::isAjax() && !Request::isPjax()){
            $menus = $alj->_getAdminMenus();
            $this->assign('menus',$menus);
            $menus_curr = $alj->_getAdminParents($url);
            $this->assign('menus_curr',$menus_curr);
        }

        $this->assign('controllerName',$this->controllerName);
    }

//    public function before_index(&$paramWhere){
//
//    }

    public function index(){
        $aorm = model($this->modelName);
        /**
         * 查询条件
         */
        $whereKeys = $aorm->getSearchFields();

        $alj = new \app\common\logic\AdminLogic($this->modelName);
        $paramWhere = $this->getParamWhere($whereKeys);
        // aop
        if(method_exists($this,'before_index')){
            $jieguo = $this->before_index($paramWhere);
            if($jieguo['err_code'] !== 0){
                $this->error($jieguo['msg']);
            }
        }

        if (!in_array('index', $this->noProjectAction) && !empty($aorm->projectIdName)) {
            // 统一附加条件 按 选择的 小区（项目）进行查询
            $paramWhere['where'][] = ['project_id','=',$this->getProjectId()];
        }

        $pagerInfo = $this->getPagerInfo($alj->_getCountByWhere($paramWhere['where']),input('p',1),$paramWhere['search']);
        $dataList = $alj->_getListByWhere($paramWhere['where'],$pagerInfo['offset'],$pagerInfo['pageSize']);

        $this->assign('datas',$dataList);
        $this->assign('search',$paramWhere['search']);
        $this->assign('whereKeys',$whereKeys);
        $this->assign($pagerInfo);
        $listFields = $aorm->getListFields();
        $this->assign('listFields',$listFields);
        $operationBtns = $aorm->getOperationBtns();
        $this->assign('operationBtns',$operationBtns);
        // 通过数据源设置的变量
        $this->assign('selectList',$this->getSelectList());

        return $this->fetch($this->templatePreFix . 'index');
    }

    //------------------------------------添加 start-----------------------------------------------------------------------
    /**
     * 添加 显示 前
     * @param $param
     */
//    protected function handle_add_get(&$param){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    /**
     * 添加 保存 前
     * @param $param
     * @return array
     */
//    protected function handle_add_post_before(&$param){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }
    public function add(){
        $param = input('param.');

        $orm = model($this->modelName);
        $formFields = $orm->getAddFields();
        if (request()->isAjax()){
            if(empty($param['id'])){
                $param['id'] = 0;
            }
            $param['project_id'] = $this->getProjectId();
            $alj = new \app\common\logic\AdminLogic($this->modelName);
            // aop
            if(method_exists($this,'handle_add_post_before')){
                $jieguo = $this->handle_add_post_before($param);
                if($jieguo['err_code'] !== 0){
                    $this->error($jieguo['msg']);
                }
            }
            // 按数据库里面定制的来进行验证
            foreach ($formFields as $field){
//                if(!array_key_exists($field['name'],$param)){
//                    $this->error($field['text'].' 未提交');
//                }

                $this->formFieldSwitchHandle($field, $param);

                if(!empty($field['validate'])){
                    if(is_array($field['validate'])){
                        // 去掉不需要验证的
                        foreach ($field['validate'] as $key => $item){
                            if(empty($item)){
                                unset($field['validate'][$key]);
                            }
                        }
                    }
                    if(is_string($field['validate'])){
                        $validate = Validate::make([
                            $field['name']  => $field['validate'],
                        ]);
                        if (!$validate->check($param)) {
                            $this->error($field['text'] . ' ' . getValidateErrorText($field['validate']));
                        }
                    }
                }
            }

            $flag = $alj->save($param);

            // aop
            if(method_exists($this,'handle_add_post_after')){
                $jieguo = $this->handle_add_post_after($param,$flag);
                if($jieguo['err_code'] !== 0){
                    $this->error($jieguo['msg']);
                }
            }
            if($flag['err_code'] === 0){
                $this->success($flag['msg'].',返回列表页',url('index'));
            }
            else{
                $this->error($flag['msg']);
            }
        }
        $this->assign('formFields',$formFields);
        // aop
        if(method_exists($this,'handle_add_get')){
            $jieguo = $this->handle_add_get($param);
            if($jieguo['err_code'] !== 0){
                $this->error($jieguo['msg']);
            }
        }
        // 通过数据源设置的变量
        $this->assign('selectList',$this->getSelectList());

        return $this->fetch($this->templatePreFix . 'add');
    }
    /**
     * 添加 保存 后
     * @param $flag
     * @return array
     */
//    protected function handle_add_post_after(&$param,&$flag){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    //------------------------------------添加 end-----------------------------------------------------------------------

    //------------------------------------编辑 start-----------------------------------------------------------------------

    /**
     * 编辑 显示前
     * @param $param
     */
//    protected function handle_edit_get_before(&$param){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }
    /**
     * 编辑 获取 model 后
     * @param $model
     */
//    protected function handle_edit_get_after(&$model){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    /**
     * 编辑前 返回 数组，如果code 等于 0 的 话 不继续
     */
//    protected function handle_edit_post_before(&$param){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    /**
     * 编辑后
     */
//    protected function handle_edit_post_after(&$param,$jieguo){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    /**
     * 编辑 基础方法 可整体重写
     * @return mixed|\think\response\Json
     */
    public function edit()
    {
        $param = input('param.');
        $alj = new \app\common\logic\AdminLogic($this->modelName);

        $orm = model($this->modelName);
        $formFields = $orm->getEditFields();

        if (request()->isAjax()){
            if(empty($param['id'])){
                $this->error('id参数错误');
            }
            $param['id'] = hashIdDecode($param['id']);
            if(empty($param['id'])){
                $this->error('id参数错误');
            }
            // aop
            if(method_exists($this,'handle_edit_post_before')){
                $jieguo = $this->handle_edit_post_before($param);
                if($jieguo['err_code'] !== 0){
                    $this->error($jieguo['msg']);
                }
            }

            // 按数据库里面定制的来进行验证
            foreach ($formFields as $field){
//                if(!array_key_exists($field['name'],$param)){
//                    $this->error($field['text'].' 未提交');
//                }
                $this->formFieldSwitchHandle($field, $param);
                if(!empty($field['validate'])){
                    if(is_array($field['validate'])){
                        // 去掉不需要验证的
                        foreach ($field['validate'] as $key => $item){
                            if(empty($item)){
                                unset($field['validate'][$key]);
                            }
                        }
                    }
                    if(is_string($field['validate'])){
                        $validate = Validate::make([
                            $field['name']  => $field['validate'],
                        ]);
                        if (!$validate->check($param)) {
                            $this->error($field['text'] . ' ' . getValidateErrorText($field['validate']));
                        }
                    }
                }
            }

            $flag = $alj->save($param);

            // aop
            if(method_exists($this,'handle_edit_post_after')){
                $jieguo = $this->handle_edit_post_after($param,$flag);
                if($jieguo['err_code'] !== 0){
                    $this->error($jieguo['msg']);
                }
            }

            if($flag['err_code']  === 0){
                $this->success($flag['msg'] . '，返回列表',url('index'));
            }
            else{
                $this->error($flag['msg']);
            }
        }

        $id = input('param.id');
        if (empty($id)){
            $this->error('参数错误',url('index'));
        }
        $id = hashIdDecode($id);
        if (empty($id)){
            $this->error('参数错误',url('index'));
        }
        $this->assign('formFields',$formFields);

        // aop
        if(method_exists($this,'handle_edit_get_before')){
            $jieguo = $this->handle_edit_get_before($param);
            if($jieguo['err_code'] !== 0){
                $this->error($jieguo['msg']);
            }
        }

        $chaxun = $alj->getModelByPk($id);
        if($chaxun['err_code'] !== 0){
            return json($chaxun);
        }
        $model = $chaxun['data'];
        $pkName = db($this->modelName)->getPk();
        $model[$pkName] = hashIdEncode($model[$pkName]);
        foreach ($formFields as $field){
            $this->showFormFieldSwitchHandle($field, $model);
        }
        // aop
        if(method_exists($this,'handle_edit_get_after')){
            $jieguo = $this->handle_edit_get_after($model);
            if($jieguo['err_code'] !== 0){
                $this->error($jieguo['msg']);
            }
        }

        $this->assign([
            'model' => $model,
        ]);

        // 通过数据源设置的变量
        $this->assign('selectList',$this->getSelectList());

        return $this->fetch($this->templatePreFix . 'edit');
    }

    //------------------------------------编辑 end-----------------------------------------------------------------------

    /**
     * 删除操作完后，可以自己再处理一些东西，可以重写
     * @param $id
     * @param $jieguo
     */
//    protected function handle_del_after($id,$jieguo){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    /**
     * 删除操作完前，可以自己再处理一些东西，可以重写
     * @param $id
     * @param $jieguo
     */
//    protected function handle_del_before($id,&$param){
//        return ['err_code' => 0 , 'msg' => '默认通过'];
//    }

    public function del(){
        $param = input('param.');
        $id = input('param.id');
        if(empty($id)){
            $this->error('请提交正确的参数');
        }
        $id = hashIdDecode($id);
        if (empty($id)){
            $this->error('参数错误',url('index'));
        }

        $alj = new \app\common\logic\AdminLogic($this->modelName);
        //中间处理 如果code 等于 0 的 话 不继续
        if(method_exists($this,'handle_del_before')){
            $jieguo = $this->handle_del_before($id,$param);
            if($jieguo['err_code'] > 0){
                $this -> error($jieguo['msg']);
            }
        }
        $jieguo = $alj->del($id);
        if(method_exists($this,'handle_del_after')){
            $jieguo = $this->handle_del_after($id,$jieguo);
            if($jieguo['err_code'] > 0){
                $this -> error($jieguo['msg']);
            }
        }
        if($jieguo['err_code'] === 0){
            $this->success($jieguo['msg']);
        }else{
            $this -> error($jieguo['msg']);
        }
    }

    /**
     * 获取自定义下拉框数据源
     * @return array
     */
    public function getSelectList(){
        return $this->selectList;
    }

    /**
     * 设置自定义下拉框数据源
     * @param $selectList
     */
    public function setSelectList($selectList){
        $this->selectList = $selectList;
    }

    /**
     * 添加自定义下拉框数据源
     * @param $key
     * @param $row
     */
    public function addSelectList($key,$row){
        $this->selectList[$key] = $row;
    }

    /**
     * 重新登陆
     * @param string $msg 提醒消息
     */
    public function reLogin($msg){
        $goBackUrl = base64_encode(request()->url());
        session('admin_go_back_url',$goBackUrl);
        $this->error($msg,url('admin/Login/login'));
    }

    /**
     * 检测小区（项目）权限
     * @return bool true 通过
     */
//    public function checkProjectAuthority(){
//        $this->adminProjectId = session('adminProjectId');
//        if(empty($this->adminProjectId)){
//            $user = session('admin_auth');
//            if(session('admin_auth_sign') == data_signature($user)){
//                $this->adminProjectId = $user['project_id'];
//            }
//            else{
//                $this->reLogin('登录信息遗失，请重新登陆！');
//            }
//        }
//
//        // 判断 如果是 -1 返回 true
//        if ($this->isSuperProject()) {
//            return true;
//        }
//        // 判断 管理员项目ID 是否等于 选择的 项目ID
//        return $this->adminProjectId == $this->getProjectId();
//    }

    /**
     * 能不能跳转
     */
    public function isChangeProject($projectId){
        $user = session('admin_auth');
        if(-1 == $user['project_id']){
            return true;
        }
        $adminLogic = new \app\common\logic\AdminLogic();
        $projectIds = $adminLogic->_getAdminProjectIds($this->adminId);
        if (empty($projectIds)) {
            return false;
        }
        $projectIds = explode(',', $projectIds);
        if (in_array($projectId, $projectIds)) {
            return true;
        }
        else{
            return false;
        }
    }

    /**
     * 表单列处理
     */
    private function formFieldSwitchHandle($field,&$postData){
        switch ($field['type']){
            case 'date_select':
            case 'datetime_select':
                if (!empty($postData[$field['name']])) {
                    $postData[$field['name']] = strtotime($postData[$field['name']]);
                }
                break;
            case 'text_money':
                if (!empty($postData[$field['name']])) {
                    $postData[$field['name']] = $postData[$field['name']] * 100;
                }
                break;
        }
    }

    /**
     * 显示时处理
     * @param $field
     * @param $model
     */
    private function showFormFieldSwitchHandle($field,&$model){
        switch ($field['type']){
            case 'datetime_select':
                if (!empty($model[$field['name']])) {
                    $model[$field['name'] . '_dd'] = date('Y-m-d',$model[$field['name']]);
                    $model[$field['name'] . '_tt'] = date('H:i:s',$model[$field['name']]);
                    $model[$field['name']] = date('Y-m-d H:i:s',$model[$field['name']]);
                }
                else{
                    $model[$field['name'] . '_dd'] = '';
                    $model[$field['name'] . '_tt'] = '';
                }
                break;
            case 'date_select':
                if (!empty($model[$field['name']])) {
                    $model[$field['name']] = date('Y-m-d',$model[$field['name']]);
                }
                break;
            case 'text_money':
                if (!empty($model[$field['name']])) {
                    $model[$field['name']] = sprintf('%.2f',$model[$field['name']] / 100);
                }
                break;
        }
    }
}